<?php

namespace app\frontend\controller;

use app\common\model\User;
use app\frontend\ApiBaseController;
use app\frontend\library\JwtAuth;
use app\frontend\validator\SignValidator;
use think\db\exception\DbException;
use think\Exception;
use think\exception\ValidateException;
use think\response\Json;

class Auth extends ApiBaseController
{
    /**
     * 用户登录
     * @return Json
     */
    public function signIn()
    {
        try {
            $params = $this->request->param();

            $this->validate($params, SignValidator::class);

            // 登录
            $user = User::login($params);

            //访问令牌
            $accessExpire = config('set.jwt.expires_in', 600);
            $accessToken = JwtAuth::createAccessToken($user->id, $accessExpire);

            //刷新令牌
            $refreshExpire = config('set.jwt.refresh_expire_in', 86400);
            $refreshToken = JwtAuth::createRefreshToken($user->id, $refreshExpire);

            return $this->jsonSuccess('login succeed', [
                'access_token' => $accessToken,
                'expires_in' => $accessExpire,
            ])->cookie('refresh_token', $refreshToken, $refreshExpire, '/', '', true, true);

        } catch (ValidateException $e) {
            return $this->jsonError($e->getError());
        } catch (Exception $e) {
            return $this->jsonError($e->getMessage());
        }
    }

    /**
     * 退出登录
     * @return Json
     * @throws DbException
     */
    public function signOut()
    {
        $refreshToken = $this->request->cookie('refresh_token');

        if ($refreshToken) {
            JwtAuth::revokeRefreshToken($refreshToken);
        }

        return $this->forceUnauthorized('logout succeed');
    }

    /**
     * 用户注册
     * @return Json
     */
    public function signUp()
    {
        try {
            $params = $this->request->param();

            $this->validate($params, SignValidator::class);

            // 注册
            User::register($params);

            return $this->jsonSuccess('sign up succeed');
        } catch (ValidateException $e) {
            return $this->jsonError($e->getError());
        } catch (Exception $e) {
            return $this->jsonError($e->getMessage());
        }
    }

    /**
     * 刷新令牌
     * @return Json
     */
    public function refreshToken()
    {
        $refreshToken = $this->request->cookie('refresh_token');

        // 1. 验证输入
        if (empty($refreshToken)) {
            return $this->jsonError('not refresh_token');
        }

        // 2. 验证Refresh Token
        $userId = JwtAuth::verifyRefreshToken($refreshToken);

        if (!$userId) {
            // 无效的Refresh Token 清除 cookie 中的 refresh_token
            return $this->forceUnauthorized('Invalid refresh token');
        }

        // 3. 生成新Access Token
        $accessExpire = config('set.jwt.expires_in', 600);
        $newAccessToken = JwtAuth::createAccessToken($userId, $accessExpire);

        // 4. 可选：刷新令牌轮换（生成新Refresh Token）
        $refreshExpire = config('set.jwt.refresh_expire_in', 86400);
        $newRefreshToken = JwtAuth::createRefreshToken($userId, $refreshExpire);

        // 撤销旧的 Refresh Token
        JwtAuth::revokeRefreshToken($refreshToken);

        // 5. 返回响应
        return $this->jsonSuccess('refresh succeed', [
            'access_token' => $newAccessToken,
            'expires_in' => $accessExpire
        ])->cookie('refresh_token', $newRefreshToken, $refreshExpire, '/', '', true, true);
    }
}